#!/usr/bin/python3
from .Base_Plugin import Base_Plugin
import os, gc, re
from openpyxl import load_workbook


class Sheet_Verify_Sheets(Base_Plugin):
    """
    检查工作簿
    """

    def __init__(self, context) -> None:
        super().__init__()
        self.context = context
        self.workspace = None
        self.source = None
        self.COL_NUM_FIELD_NAME = 1
        self.COL_NUM_COLUMN_TYPE = 2
        self.COL_NUM_IS_NOT_NULL = 3
        self.COL_NUM_UNIQUE = 4
        self.COL_NUM_SINGLE_VALIDATION = 7
        self.COL_NUM_DESENSITIZATION_LEVEL = 8
        self.COL_NUM_IS_WRITE_LUCENE = 9
        self.COL_NUM_DATRTYPE = 2
        self.yes_no = ["Y", "N"] # 是否
        self.desensitization_levels = ["A", "B", "C", "D"] # 脱敏级别

    def check_sheet(self, sheet):
        """
        检查工作表
        """
        self.check_title(sheet)
        self.check_column_legal(sheet)
        self.check_column_type(sheet)
        self.check_is_not_null(sheet)
        self.check_unique(sheet)
        self.check_single_verify(sheet)

    def check_title(self, sheet):
        assert len(sheet["A1"].value) > 0, self.error_log(
            f"""{sheet.name}表名配置无效"""
        )
        assert len(sheet["A2"].value) > 0, self.error_log(
            f"""{sheet.name}表代号配置无效"""
        )
        assert "{{" not in sheet["A1"].value, self.error_log(
            f"""{sheet.name}表名配置无效"""
        )
        assert "}}" not in sheet["A1"].value, self.error_log(
            f"""{sheet.name}表名配置无效"""
        )
        assert "{{" not in sheet["A2"].value, self.error_log(
            f"""{sheet.name}表代号配置无效"""
        )
        assert "}}" not in sheet["A2"].value, self.error_log(
            f"""{sheet.name}表代号配置无效"""
        )

    def check_column_legal(self, sheet):
        """
        检查列名合法性
        """
        column_list = list()
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if "->" in row[1].value:
                column_name = row[1].value.split("->")[1]
                assert (
                    "\n" not in column_name and "\t" not in column_name
                ), self.error_log(f"""{sheet['A2'].value}.{column_name}存在转义字符""")
                assert (
                    re.match(r"^[a-z]+(_*[a-z0-9]+)+$", column_name) is not None
                ), self.error_log(
                    f"""非法的列名称 -> {sheet['A2'].value}.{column_name}"""
                )
                assert column_name not in column_list, self.error_log(
                    f"""{sheet['A2'].value}.{column_name}列重复声明"""
                )
            else:
                assert (
                    "\n" not in row[1].value and "\t" not in row[1].value
                ), self.error_log(f"""{sheet['A2'].value}.{row[1].value}存在转义字符""")
                assert (
                    re.match(r"^[a-zA-Z]+(_*[a-zA-Z0-9]+)+$", row[1].value) is not None
                ), self.error_log(
                    f"""非法的列名称 -> {sheet['A2'].value}.{row[1].value}"""
                )
                assert row[1].value not in column_list, self.error_log(
                    f"""{sheet['A2'].value}.{row[1].value}列重复声明"""
                )
            column_list.append(row[1].value)

    def check_column_type(self, sheet):
        """
        检查列字段类型
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_COLUMN_TYPE].value is None:
                break

            assert (
                "\n" not in row[self.COL_NUM_COLUMN_TYPE].value
                and "\t" not in row[self.COL_NUM_COLUMN_TYPE].value
            ), self.error_log(f"""{sheet['A2'].value}.{row[1].value}存在转义字符""")

    def check_is_not_null(self, sheet):
        """
        检查非空设置
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_FIELD_NAME].value is None:
                break
            is_not_null = row[self.COL_NUM_IS_NOT_NULL].value
            if is_not_null is not None:
                assert is_not_null in self.yes_no, self.error_log(
                    f"""{sheet['A2'].value}.{row[1].value}是否非空配置无效"""
                )

    def check_unique(self, sheet):
        """
        检查唯一键设置
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_FIELD_NAME].value is None:
                break
            unique = row[self.COL_NUM_UNIQUE].value
            if unique is not None:
                assert unique in self.yes_no, self.error_log(
                    f"""{sheet['A2'].value}.{row[1].value}是否唯一键配置无效"""
                )

    def check_single_verify(self, sheet):
        """
        检查是否单向校验设置
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_FIELD_NAME].value is None:
                break
            single_verify = row[self.COL_NUM_SINGLE_VALIDATION].value
            if single_verify is not None:
                assert single_verify in self.yes_no, self.error_log(
                    f"""{sheet['A2'].value}.{row[1].value}是否单向校验配置无效"""
                )

    def check_encrypt(self, sheet):
        """
        检查脱敏级别
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_FIELD_NAME].value is None:
                break
            is_write_lucene_index: str = row[self.COL_NUM_DESENSITIZATION_LEVEL].value
            assert is_write_lucene_index is not None, self.error_log(f"""{sheet['A2'].value}.{row[1].value}脱敏级别配置缺失""")
            assert is_write_lucene_index in self.desensitization_levels, self.error_log(f"""{sheet['A2'].value}.{row[1].value}脱敏级别配置无效""")

    def check_write_lucene_index(self, sheet):
        """
        检查是否写入lucene索引
        """
        for row in sheet.rows:
            if row[0].row < self.project_config["列字段开始行"]:
                continue

            if row[self.COL_NUM_FIELD_NAME].value is None:
                break
            is_write_lucene_index = row[self.COL_NUM_IS_WRITE_LUCENE].value
            assert is_write_lucene_index is not None, self.error_log(f"""{sheet['A2'].value}.{row[1].value}是否写入Lucene配置缺失""")
            assert is_write_lucene_index in self.yes_no, self.error_log(f"""{sheet['A2'].value}.{row[1].value}是否写入Lucene配置无效""")



    def run(self, workspace, source):
        workbook = load_workbook(os.path.join(workspace, source))
        _directory = workbook["目录"]
        _index = 0
        for row in _directory.rows:
            if _index < 1:
                _index += 1
                continue

            table_name = row[1].value
            if table_name is None:
                break
            table_name = table_name.strip()
            table_description = row[2].value.strip()

            self.check_sheet(workbook[table_description])
            self.processed += 1
        del workbook
        gc.collect()
        return source
